﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using SdmxMl.Helper;
using SdmxMl.Common;
using SdmxMl.Structure;
using SdmxMl.Manager;


namespace SdmxMl.Panels
{
    /// <summary>
    /// Dialog for location of references, can act also for replacements
    /// </summary>
    public partial class DlgMemoryRef : Form
    {
        #region Internal Members

        #endregion

        #region C'tor

        public DlgMemoryRef()
        {
            InitializeComponent();

            // Raise default state for replace controls
            textBoxUrnReplace.Enabled = false;
            textBoxUrnReplace_TextChanged(null, EventArgs.Empty);
        }
        #endregion

        #region Update reference to localize

        /// <summary> Update reference to localize </summary>
        /// <param name="tv">Artefact tree view</param>
        /// <param name="s">Artefact container</param>
        public void Update(TreeView tv)
        {
            textBoxUrn.Text = string.Empty;
            dataGridViewRef.DataSource = null;

            //If item selected in tree is conceptscheme, concept or code or codelist, prepare urn
            if (tv != null && tv.SelectedNode != null)
            {
                Artefact a = tv.SelectedNode.Tag is Artefact ?
                    tv.SelectedNode.Tag as Artefact :
                    TreeHelper.GetParentArtefact(tv.SelectedNode);

                ConceptType co = tv.SelectedNode.Tag as ConceptType;

                if (a != null)
                {
                    if (a is CodeListType)
                        textBoxUrn.Text = UrnManager.FullIdToUrn(SdmxArtefactType.CodeLists, a.FullIdent);
                    else if (co != null)
                        textBoxUrn.Text = UrnManager.FullIdToUrn(SdmxArtefactType.Concepts, a.FullIdent, co, null);
                    else if (a is ConceptSchemeType)
                        textBoxUrn.Text = UrnManager.FullIdToUrn(SdmxArtefactType.Concepts, a.FullIdent);
                }

                // Activate search if urn is already given
                if (textBoxUrn.Text.Length > 0)
                    buttonSearchRef_Click(buttonSearchRef, EventArgs.Empty);
            }
        }
        #endregion

        #region Buttons Events

        private void dataGridViewRef_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex >= 0)
                buttonNavigate_Click(sender, EventArgs.Empty);
        }

        private ReferenceItem FindSelectedRow()
        {
            ReferenceItem findRow = null;
            if (dataGridViewRef.DataSource != null)
            {
                BindingManagerBase bm = dataGridViewRef.BindingContext[dataGridViewRef.DataSource, dataGridViewRef.DataMember];
                if (bm.Count > 0 && bm.Current != null)
                    findRow = bm.Current as ReferenceItem;
            }

            return findRow;
        }

        private void buttonNavigate_Click(object sender, EventArgs e)
        {
            try
            {
                ReferenceItem refItem = FindSelectedRow();
                if (refItem != null)
                {
                    // If URN try to get it if not already in memory
                    ArtefactRefTyped art = UrnManager.UrnToArtefactRefTyped(refItem.Urn);
                    if (art != null)
                    {
                        UrnParser p = new UrnParser(refItem.Urn);

                        // If already in memory, navigate otherwhile get from regidtry
                        if (NavigationManager.LocatenavigateProject(art.Type, art.FullIdent, p) == null)
                            NavigationManager.NavigateWithRegistry(art.Type, art.FullIdent, true, p);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary> Search references Event </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void buttonSearchRef_Click(object sender, EventArgs e)
        {
            try
            {
                if (textBoxUrn.Text.Length > 0)
                {
                    UrnParser up = new UrnParser(textBoxUrn.Text);
                    if (up.IsSupported)
                    {
                        ReferenceUsage ru = new ReferenceUsage(ReferenceManager.GetSmContainerImage(), up);

                        Dictionary<string, ReferenceItem> dico = ru.GetMemoryReferences();

                        List<ReferenceItem> list = new List<ReferenceItem>(dico.Values);
                        dataGridViewRef.DataSource = list;
                    }
                    else
                        MessageBox.Show("Invalid reference syntax.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                    MessageBox.Show("Please specifies an URN for Concept or Codelist", "Caution", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        #endregion

        #region Replace controls enabling

        private void checkBoxReplace_CheckedChanged(object sender, EventArgs e)
        {
            textBoxUrnReplace.Enabled = checkBoxReplace.Checked;
            textBoxUrnReplace_TextChanged(sender, e);
        }

        private void textBoxUrnReplace_TextChanged(object sender, EventArgs e)
        {
            buttonReplace.Enabled = checkBoxReplace.Checked && textBoxUrnReplace.Text.StartsWith(UrnManager.UrnBase) &&
                textBoxUrn.Text.StartsWith(UrnManager.UrnBase);
        }
        #endregion

        #region Grid Events

        /// <summary>
        /// Select / Unselect All in annotations list
        /// </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void dataGridViewAnnot_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.ColumnIndex == 0)
            {
                dataGridViewRef.EndEdit();

                List<ReferenceItem> list = dataGridViewRef.DataSource as List<ReferenceItem>;
                if (list != null && list.Count > 0)
                {
                    bool selectedFlag = !list[0].Selected;

                    foreach (ReferenceItem r in list)
                        r.Selected = selectedFlag;

                    dataGridViewRef.Refresh();
                }
            }
        }
        #endregion

        /// <summary> Activates replacement reference of selected items in datagrid view</summary>
        /// <param name="sender"></param><param name="e"></param>
        private void buttonReplace_Click(object sender, EventArgs e)
        {
            try
            {
                if (textBoxUrn.Text.Length > 0)
                {
                    UrnParser upSrc = new UrnParser(textBoxUrn.Text);
                    UrnParser upTarget = new UrnParser(textBoxUrnReplace.Text);
                    if (upSrc.IsSupported && upTarget.IsSupported)
                    {
                        List<ReferenceItem> list = dataGridViewRef.DataSource as List<ReferenceItem>;

                        ReplaceRefMgr rpl = new ReplaceRefMgr(upSrc, upTarget, list, ReferenceManager.GetSmContainerImage());
                        int count = rpl.ProcessReplace();
                        MessageBox.Show(this, "Replace count: " + count.ToString(), "Replace", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Replace Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
    }
}
